<?php
/**
 * Each engineer has a duty to keep the code elegant
 * Created by wolffy.
 * Author @wolffy<13750088090@sina.cn>
 * Date: 2018/8/19
 * Time: 19:30
 */
namespace App\Services;

use App\Handlers\ApiResponse;
use App\Repositories\CardLogoRepository;
use App\Repositories\RepaymentBillRepository;
use App\Repositories\RepaymentPlanConsumeRepository;
use App\Repositories\RepaymentPlanRepaymentRepository;
use App\Repositories\RepaymentPlanRepository;
use App\Repositories\UserCreditCardRepository;
use App\Repositories\UserPassageRegisterRepository;
use App\Repositories\UserRepository;

class CreditCardService
{
    use ApiResponse;

    protected $userCreditCardRepository;
    protected $repaymentBillRepository;
    protected $repaymentPlanRepository;
    protected $cardLogoRepository;
    protected $userPassageRegisterRepository;
    protected $repaymentPlanRepaymentRepository;
    protected $repaymentPlanConsumeRepository;

    public function __construct(UserRepository $userRepository, UserCreditCardRepository $userCreditCardRepository,
                                RepaymentBillRepository $repaymentBillRepository, RepaymentPlanRepository $repaymentPlanRepository,
                                CardLogoRepository $cardLogoRepository, UserPassageRegisterRepository $userPassageRegisterRepository,
                                RepaymentPlanRepaymentRepository $repaymentPlanRepaymentRepository, RepaymentPlanConsumeRepository $repaymentPlanConsumeRepository)
    {
        $this->userRepository = $userRepository;
        $this->userCreditCardRepository = $userCreditCardRepository;
        $this->repaymentBillRepository = $repaymentBillRepository;
        $this->repaymentPlanRepository = $repaymentPlanRepository;
        $this->cardLogoRepository = $cardLogoRepository;
        $this->userPassageRegisterRepository = $userPassageRegisterRepository;
        $this->repaymentPlanRepaymentRepository = $repaymentPlanRepaymentRepository;
        $this->repaymentPlanConsumeRepository = $repaymentPlanConsumeRepository;
    }

    /**
     * 信用卡列表
     */
    public function creditCardList($userId)
    {
        $data = $this->userCreditCardRepository->getUserCreditCardListList($userId);
        return $this->responseJson(0, $data);
    }

    /**
     * 更新信用卡
     * @param $id
     * @param $billDay
     * @param $repaymentDay
     * @return \Illuminate\Http\JsonResponse
     */
    public function updateCreditCard($userId, $creditId, $billDay, $repaymentDay, $creditLines, $repaymentMoneys)
    {
        if ($billDay == $repaymentDay) {
            return $this->responseJson(422, [], false, '账单日与还款日相等', '账单日与还款日相等');
        }
        $creditIsExist = $this->userCreditCardRepository->validateCreditCardIsUser($creditId, $userId);
        if (empty($creditIsExist)) {
            return $this->responseJson(10306);//信用卡不存在
        } else {
            $userCreditCardRepository = $this->userCreditCardRepository->byId($creditId);
            $userCreditCardRepository->update([
                'bill_day' => $billDay,
                'repayment_day' => $repaymentDay,
                'credit_lines' => $creditLines,
                'update_time' => time()
            ]);
            //一个月有上个和这个还款日，两个的处理
            $monthBillDate = getMonthBillDate($billDay, $repaymentDay);
            $bill = $this->repaymentBillRepository->getRepaymentBill($userId, $creditId, $monthBillDate);
            $billRepaymentDate = billRepaymentDate($billDay, $repaymentDay);
            if (date('Y-m') != $monthBillDate) {
                $billRepaymentDate = [
                    'bill_last_date' => date('Ymd', strtotime("-1 months", strtotime($billRepaymentDate['bill_last_date']))),//上个月账单日
                    'repayment_last_date' => date('Ymd', strtotime("-1 months", strtotime($billRepaymentDate['repayment_last_date']))),//上个还款日
                    'bill_date' => $billRepaymentDate['bill_last_date'],//本月账单日
                    'repayment_date' => $billRepaymentDate['repayment_last_date'],//还款日
                    'diff_days' => diffDate($billRepaymentDate['bill_last_date'], $billRepaymentDate['repayment_last_date']),
                ];
            }
            $repaymentMoneyAll = roundNo($repaymentMoneys);//不四舍五入保留两位
            if (!empty($bill)) {
                $bill->update([
                    'last_bill_date' => strtotime($billRepaymentDate['bill_last_date']) + 86400,
                    'bill_date' => strtotime($billRepaymentDate['bill_date']),
                    'repayment_date' => strtotime($billRepaymentDate['repayment_date']),
                    'repayment_bill_money' => $repaymentMoneyAll,
                    'lowest_repayment_money' => ceilDecimal($repaymentMoneyAll * 0.1, 2),//本期最低应还金额
                    'bill_status' => billStatus($billRepaymentDate['bill_date'], $billRepaymentDate['repayment_date'], $repaymentMoneys),
                    'update_time' => time(),
                ]);
            } else {
                //添加本期账单
                $bill = [
                    'bill_sn' => makeOrderNo(),
                    'user_id' => $userId,
                    'credit_card_id' => $creditId,
                    'last_bill_date' => strtotime($billRepaymentDate['bill_last_date']) + 86400,
                    'bill_date' => strtotime($billRepaymentDate['bill_date']),
                    'repayment_date' => strtotime($billRepaymentDate['repayment_date']),
                    'repayment_bill_money' => $repaymentMoneyAll,
                    'lowest_repayment_money' => ceilDecimal($repaymentMoneyAll * 0.1, 2),//本期最低应还金额
                    'bill_status' => billStatus($billRepaymentDate['bill_date'], $billRepaymentDate['repayment_date'], $repaymentMoneyAll),
                    'month_bill_date' => $monthBillDate,
                    'create_time' => time(),
                ];
                $this->repaymentBillRepository->create($bill);
            }
            return $this->responseJson(0);
        }
    }

    /**
     * 删除或解绑信用卡
     * @param $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function destroyCreditCard($id, $userId)
    {
        $creditIsExist = $this->userCreditCardRepository->validateCreditCardIsUser($id, $userId);
        if (empty($creditIsExist)) {
            return $this->responseJson(10306);//信用卡不存在
        } else {
            //一个月有上个和这个还款日，两个的处理
            $monthBillDate = getMonthBillDate($creditIsExist->bill_day, $creditIsExist->repayment_day);
            //获取本月账单
            $bill = $this->repaymentBillRepository->getRepaymentBill($userId, $id, $monthBillDate);
            if (!empty($bill)) {
                //是否有待执行和执行中的记录
                $isHasRunOrNoRun = $this->repaymentPlanRepository->isHasRunOrNoRun($bill->id);
                if (!empty($isHasRunOrNoRun->toArray())) {
                    return $this->responseJson(10308);//该卡的还款计划在执行中暂不允许解绑
                }
            }
            $userCreditCardRepository = $this->userCreditCardRepository->byId($id);
            //信用卡号为空是未认证卡号则删除 不为空则更新
            if (empty($userCreditCardRepository->bank_no)) {
                $userCreditCardRepository->delete();
            } else {
                $userCreditCardRepository->update(['is_bind' => 0, 'update_time' => time()]);
                //解绑开通交易卡
                $this->userPassageRegisterRepository->updateOpenCardToCreditCard(1, $userId, $id, 0);
            }
            return $this->responseJson(0);
        }
    }

    /**
     * 账单明细
     * @param $userId
     * @param $creditCardId
     * @return \Illuminate\Http\JsonResponse
     */
    public function billDetail($userId, $creditCardId)
    {
        $creditIsExist = $this->userCreditCardRepository->validateCreditCardIsUser($creditCardId, $userId);
        if (empty($creditIsExist)) {
            return $this->responseJson(0);
        }
        //一个月有上个和这个还款日，两个的处理
        $monthBillDate = getMonthBillDate($creditIsExist->bill_day, $creditIsExist->repayment_day);
        $record = $this->repaymentBillRepository->getRepaymentRecord($userId, $creditCardId);
        $data = [];
        foreach ($record as $key=>$value) {
            $data[$key] = $value;
            if ($value['month_bill_date'] > $monthBillDate) {
                unset($data[$key]);
            }
        }
        $data = array_values($data);
        return $this->responseJson(0, $data);
    }

    /**
     * 还款记录
     * @param $userId
     * @param $creditCardId
     * @return \Illuminate\Http\JsonResponse
     */
    public function repaymentRecord($userId, $creditCardId)
    {
        $record = $this->repaymentBillRepository->getRepaymentRecord($userId, $creditCardId);
        if (!empty($record)) {
            //找出关联的还款计划
            $data = [];
            foreach ($record as $key=>$value) {
                $repaymentPlan = $this->repaymentPlanRepository->repaymentPlanRecord($value['bill_id']);
                $data[$key] = $value;
                $data[$key]['detail'] = $repaymentPlan;
            }
        } else {
            $data = [];
        }
        return $this->responseJson(0, $data);
    }

    public function repaymentPlan($userId, $creditCardId = 0, $status, $month, $page)
    {
        $data = [];
        if ($creditCardId > 0) {
            $creditCard = $this->userCreditCardRepository->byId($creditCardId);
            if (empty($creditCard)) {
                return $this->responseJson(10306);//信用卡不存在
            }
            $data = $this->getPlanData($userId, $creditCardId, $creditCard, $status, $month, $page);
        } else {
            $creditCard = $this->userCreditCardRepository->getCardToBind($userId);
            if (empty($creditCard->toArray())) {
                return $this->responseJson(0);
            }
            foreach ($creditCard as $key=>$value) {
                $data[$key] = $this->getPlanData($userId, $value['id'], $value, $status, $month, $page);
            }
            $data = $this->arrayDeal($data);
        }
        return $this->responseJson(0, $data);
    }

    public function arrayDeal($data)
    {
        $arr = [];
        foreach ($data as $key=>$value) {
            if (!empty($value)) {
                foreach ($value as $k=>$v) {
                    $arr[] = $v;
                }
            }
        }
        return $arr;
    }

    public function getPlanData($userId, $creditCardId, $creditCard, $status, $month, $page)
    {
        $data = [];
        $repaymentPlan = $this->repaymentPlanRepository->repaymentPlan($userId, $creditCardId, $status, $month, $page);
        if (!empty($repaymentPlan)) {
            $cardLogo = $this->cardLogoRepository->findToBankCode($creditCard['bank_code']);
            foreach ($repaymentPlan as $key=>$item) {
                unset($item['user_id']);
                $data[$key] = $item;
                $alreadyRepaymentMoney = $this->repaymentPlanRepaymentRepository->repaymentSuccessSum($item['id']);
                $repaymentEveryDayAll = $this->repaymentPlanRepaymentRepository->planRepaymentAll($item['id'])->toArray();
                $repaymentStartDate = array_first($repaymentEveryDayAll)['repayment_every_time_date'];
                $repaymentEndDate = array_last($repaymentEveryDayAll)['repayment_every_time_date'];
                $data[$key]['already_repayment_money'] = $alreadyRepaymentMoney;
                $data[$key]['already_repayment_money'] = $alreadyRepaymentMoney;
                $data[$key]['repayment_start_date'] = $repaymentStartDate;
                $data[$key]['repayment_end_date'] = $repaymentEndDate;
                $data[$key]['fail_message'] = $this->repaymentFailMessage($item['id']);
                $data[$key]['credit_card_id'] = $creditCard['id'];
                $data[$key]['bank_no'] = $creditCard['bank_no'];
                $data[$key]['bank_code'] = $creditCard['bank_code'];
                $data[$key]['bank_description'] = $creditCard['bank_description'];
                $data[$key]['card_logo_url'] = !empty($cardLogo) ? getOssImageUrl($cardLogo->card_logo_url) : '';
            }
        }
        return $data;
    }

    public function repaymentFailMessage($repaymentPlanId)
    {
        $consumeFailMessage = $this->repaymentPlanConsumeRepository->byFailMessage($repaymentPlanId);
        if (!empty($consumeFailMessage)) {
            return $consumeFailMessage->fail_message;
        }
        $repaymentFailMessage = $this->repaymentPlanRepaymentRepository->byFailMessage($repaymentPlanId);
        if (!empty($repaymentFailMessage)) {
            return $repaymentFailMessage->fail_message;
        }
        return '';
    }

    public function updateBillStatus($billId, $billStatus)
    {
        $bill = $this->repaymentBillRepository->byId($billId);
        $bill->update([
            'bill_status' => $billStatus //账单状态：0待出账 1待更新 2待还清 3已还清 4已逾期
        ]);
        return $this->responseJson(0);
    }
}
